#pragma once

#include "LvDevice.hpp"

#include<string>
#include<vector>

struct PipelineConfigInfo
{
	PipelineConfigInfo() = default;
	PipelineConfigInfo(const PipelineConfigInfo&) = delete;
	PipelineConfigInfo& operator=(const PipelineConfigInfo&) = delete;

	VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo{};
	VkPipelineRasterizationStateCreateInfo rasterizationInfo{};
	VkPipelineMultisampleStateCreateInfo multisampleInfo{};
	VkPipelineColorBlendAttachmentState colorBlendAttachment{};
	VkPipelineDepthStencilStateCreateInfo depthStencilInfo{};
	std::vector<VkDynamicState> dynamicStateEnables;
	VkPipelineLayout pipelineLayout = nullptr;
	VkRenderPass renderPass = nullptr;
	uint32_t subpass = 0;
};

class LvPipeline
{
public:
	LvPipeline(
		LvDevice& device,
		const std::string& vertPath,
		const std::string& fragPath,
		const PipelineConfigInfo& configInfo);
	~LvPipeline();

	LvPipeline(const LvPipeline&) = delete;
	LvPipeline& operator=(const LvPipeline&) = delete;

	void bind(VkCommandBuffer commandBuffer);

	static void defaultPipelineConfigInfo(PipelineConfigInfo& info);


private:
	static std::vector<char> readFile(const std::string& filepath);

	void createGraphicsPipeline(
		const std::string& vertPath,
		const std::string& fragPath,
		const PipelineConfigInfo& configInfo);
	
	void createShaderModule(const std::vector<char>& code, VkShaderModule* shaderModule);


	LvDevice& lvDevice;
	VkPipeline graphicsPipeline;
	VkShaderModule vertShaderModule;
	VkShaderModule fragShaderModule;


};

